package org.NooLab.openNLP.bst;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Vector;

import org.NooLab.structures.nlp.PoStagged;




public class ParseTree implements Serializable{
 
	private static final long serialVersionUID = -5140867374990734315L;
	
	
	ArrayList<TreeItem> treeItems = new ArrayList<TreeItem>() ;
	ArrayList<SentenceChunk> chunks = new ArrayList<SentenceChunk>() ; 
	
	

	ArrayList<PoStagged> verbPhrase  = new ArrayList<PoStagged> (); 
	ArrayList<PoStagged> nounPhrase  = new ArrayList<PoStagged> ();
	ArrayList<PoStagged> obj         = new ArrayList<PoStagged> ();
	ArrayList<PoStagged> conditions  = new ArrayList<PoStagged> ();
	
	ArrayList<PoStagged> nouns       = new ArrayList<PoStagged> (); 
	ArrayList<PoStagged> conditional = new ArrayList<PoStagged> ();

	// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

	public ParseTree(){
		initRoot();
	}
	// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
	

	private void initRoot(){
		TreeItem tItem;
		
		tItem = new TreeItem();
		
		tItem.leafigerR = tItem ;
		tItem.leafigerL = tItem ;
		tItem.rootiger = tItem ;
		
		tItem.left  = -1;
		tItem.right = -1;
		
		tItem.bindingValue = -100.0;
		tItem.ruleID = -1;
		
		tItem.index = 0;
		treeItems.add(tItem) ;
	}
	
	
	/**
	 * after initializing, there are leafCount+1 items in the tree, 
	 * which consists then only from leafs!
	 * 
	 * before initializing, there is already 1 item in there, the root  
	 * @param leafCount
	 */
	public void initialize( int leafCount ){
		TreeItem tItem;
		
		if (treeItems.size()==0){
			initRoot();
		}
		
		for (int i=1;i<=leafCount;i++){
			tItem = new TreeItem();

			tItem.index = i;
			tItem.left  = i;
			tItem.right = i;
			
			tItem.leftNeighborItem  = treeItems.get(i-1);
			tItem.rightNeighborItem = treeItems.get(0); // will be overwritten by next add(), if there is one at all
			
			tItem.leafigerR = treeItems.get(0) ; // upwards and downwards we only find the root...
			tItem.leafigerL = treeItems.get(0) ;
			tItem.rootiger  = treeItems.get(0) ;
			
			treeItems.add(tItem) ;
			 
			tItem.leftNeighborItem.rightNeighborItem = tItem;
				
			treeItems.get(0).leftNeighborItem = tItem ;
		}
		 
	}

	public int indexOfLabel( String labelstr ) {
		return indexOfLabel( labelstr ,0);
	}
	public int indexOfLabel( String labelstr , int offset) {
		int pos=-1,p,start=0;
		String str="";
		TreeItem tit;
		
		if (offset>0){
			start=offset;
		}
		if (offset>treeItems.size()){
			return pos;
		}
		
		if (start<0){
			start=0;
		}
		for (int i=start;i<treeItems.size();i++){
			tit = treeItems.get(i);
			
			// branches consist of "[word] <TAG>"
			
 			if (tit!=null){
				str = tit.branches;
				
				if (str!=null){
					p = str.lastIndexOf("<");
					if (p > 0) {
						str = str.substring(0, p - 1).trim();
					}
				}
			}
			if ((str!=null) && (str.length()>0) && (str.contentEquals(labelstr))){
				pos = i;
				break;
			}
		}
		
		
		return pos ;
	}
	
	
	// ------------------------------------------------------------------------
	
	public int count(){
		return treeItems.size();
	}
	
	public int size(){
		return treeItems.size();
	}

	public String toString(int mode){
		String str="", tits;
		int p;
		
		for (int i=1;i<treeItems.size();i++){
			tits = treeItems.get(i).getBranches();
			if (mode<=0){
				p=tits.indexOf("<");
				if (p>0){
					tits = tits.substring(0,p-1).trim(); 
				}
			}
			str = str+ tits+" ";
		}
		str = str.trim();
		return str;
	}
	
	
	public ArrayList<TreeItem> getTreeItems() {
		return treeItems;
	}

	public void setTreeItems(ArrayList<TreeItem> treeItems) {
		this.treeItems = treeItems;
	}

	public ArrayList<SentenceChunk> getChunks() {
		return chunks;
	}

	public ArrayList<PoStagged> getVerbPhrase() {
		return verbPhrase;
	}

	public ArrayList<PoStagged> getNounPhrase() {
		return nounPhrase;
	}

	public ArrayList<PoStagged> getObj() {
		return obj;
	}

	public ArrayList<PoStagged> getConditions() {
		return conditions;
	}

	public ArrayList<PoStagged> getNouns() {
		return nouns;
	}

	public ArrayList<PoStagged> getConditional() {
		return conditional;
	}
}
